package ttsclient

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"net/url"
	"strings"
	"sync"

	"github.com/gorilla/websocket"
)

type TTSClient struct {
	wsConn      *websocket.Conn
	requestChan chan RequestData
	responseChan chan string
	mu          sync.Mutex
}

var (
	instance *TTSClient
	once     sync.Once
)

// 定义请求结构
type RequestData struct {
	Index  string `json:"index"`
	TxtMP3 string `json:"txt-mp3"`
}

// 获取单例 TTS 客户端实例
func GetTTSClient(wsURL string) (*TTSClient, error) {
	var err error
	once.Do(func() {
		instance, err = newTTSClient(wsURL)
		if err != nil {
			log.Fatalf("初始化 TTS 客户端失败: %v", err)
		}
	})
	return instance, err
}

// 创建新的 TTS 客户端，初始化 WebSocket 连接和请求/响应管理
func newTTSClient(wsURL string) (*TTSClient, error) {
	// 启动 WebSocket 连接
	u := url.URL{Scheme: "ws", Host: wsURL}
	log.Printf("连接到 %s", u.String())

	// 建立 WebSocket 连接
	conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
	if err != nil {
		return nil, fmt.Errorf("WebSocket 连接出错: %w", err)
	}

	client := &TTSClient{
		wsConn:      conn,
		requestChan: make(chan RequestData, 10),  // 缓冲通道，用于管理 TTS 请求
		responseChan: make(chan string, 10),     // 用于处理来自 WebSocket 的响应
	}

	// 启动 Goroutine 来接收 WebSocket 消息
	go client.listenForMessages()

	// 启动 Goroutine 来处理 TTS 请求队列
	go client.processRequests()

	return client, nil
}

// 处理请求队列
func (c *TTSClient) processRequests() {
	for req := range c.requestChan {
		err := c.sendHTTPRequest(req)
		if err != nil {
			log.Printf("发送请求失败: %v", err)
			continue
		}
		log.Printf("TTS 请求发送成功: %+v", req)
	}
}

// 发送生成 TTS 的 HTTP 请求
func (c *TTSClient) sendHTTPRequest(data RequestData) error {
	// 将数据编码为 JSON
	jsonData, err := json.Marshal(data)
	if err != nil {
		return fmt.Errorf("JSON 编码出错: %w", err)
	}

	// 向服务器发送 POST 请求
	resp, err := http.Post("http://localhost:7001/generate", "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		return fmt.Errorf("HTTP 请求出错: %w", err)
	}
	defer resp.Body.Close()

	// 检查服务器响应
	if resp.StatusCode == http.StatusOK {
		log.Printf("任务 %s 已成功发送", data.Index)
	} else {
		log.Printf("任务 %s 发送失败，状态码: %d", data.Index, resp.StatusCode)
	}

	return nil
}

// 向请求队列发送 TTS 请求
func (c *TTSClient) SendTTSRequest(filename string, text string) {
	data := RequestData{
		Index:  filename,
		TxtMP3: text,
	}

	// 将请求发送到请求通道，队列式处理
	c.requestChan <- data
}

// 监听 WebSocket 消息
func (c *TTSClient) listenForMessages() {
	for {
		_, message, err := c.wsConn.ReadMessage()
		if err != nil {
			log.Println("读取 WebSocket 消息出错:", err)
			return
		}

		// 将消息转为字符串
		msg := string(message)

		// 根据消息类型进行处理
		if strings.Contains(msg, "failed") {
			log.Printf("收到消息: %s", msg)
			c.responseChan <- msg  // 发送失败消息到响应通道
		} else if strings.Contains(msg, "done") {
			log.Printf("收到完成消息: %s", msg)
			c.responseChan <- msg  // 发送成功消息到响应通道
		} else {
			log.Printf("收到未识别的消息: %s", msg)
		}
	}
}

// 获取响应通道
func (c *TTSClient) GetResponseChan() <-chan string {
	return c.responseChan
}

// 关闭 WebSocket 连接
func (c *TTSClient) Close() error {
	close(c.requestChan)
	return c.wsConn.Close()
}
